<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<h1>{{name}}</h1>
<h2>{{age}}</h2>
<h2>{{a}}</h2>
<h3>{{abc}}</h3>

<body>

</body>
<script>
    // export default {
    //     data() {
    //         return {
    //             name: '张三',
    //             age: 18,
    //             a: {
    //                 b: {
    //                     c: 1
    //                 }
    //             }
    //         }
    //     },
    //     methods: {
    //         changeName() {
    //             this.name = '王五'
    //         }
    //     }
    // }


    const data = {
        name: '张三',
        age: 18,
        a: {
            b: {
                c: 1
            }
        }
    }

    // 给对象中的每个属性设置getter setter

    function defineReactive(obj) {
        // 遍历对象的每一个 key
        Object.keys(obj).forEach(key => {
            let val = obj[key]; // 当前属性的值

            // 如果值仍然是对象，递归处理
            if (typeof val === 'object' && val !== null) {
                defineReactive(val);
            }

            // 使用 defineProperty 劫持属性访问
            Object.defineProperty(obj, key, {
                enumerable: true,   // 可枚举
                configurable: true, // 可重新定义
                get() {
                    console.log(`获取属性：${key} ->`, val);
                    // 进行一个依赖的收集 收集依赖了这个属性的dom元素 name->h1
                    return val;
                },
                set(newVal) {
                    console.log(`设置属性：${key}，新值：`, newVal);
                    // 如果新值是对象，继续递归劫持
                    if (typeof newVal === 'object' && newVal !== null) {
                        defineReactive(newVal);
                    }
                    // 触发依赖更新 name -> dom 更新
                    val = newVal;
                }
            });
        });
    }


    defineReactive(data);

    console.log(data.name);  // 触发 getter
    data.name = '李四';       // 触发 setter
    data.a.b.c = 2;          // 触发深层 getter/setter


    // data.abc = 123 不是响应式的
    // this.$set(data, 'abc', 123) 添加响应式
    // delete data.name  不是响应式
    // this.$delete(data, 'name') 删除响应式

    // abc 是否是响应式的？


    // Vue2中数组响应式：
    // 1. 通过重写数组的7个方法来实现



</script>

</html>